﻿using Application.Common.Interfaces;
using Common.Utils;
using Common.Utils.Extensions;
using FluentValidation;
using Microsoft.EntityFrameworkCore;

namespace Application.Features.Users.Commands.Update;

public class UpdateUserCommandValidator : AbstractValidator<UpdateUserCommand>
{
    private readonly IApplicationDbContext _context;
    public UpdateUserCommandValidator(IApplicationDbContext context)
    {
        _context = context;
        RuleFor(v => v.Email)
             .Must(BeValidEmail!).WithMessage($"邮箱格式错误！");

        RuleFor(v => v.PhoneNumber)
             .Must(BeValidPhoneNumber!).WithMessage($"号码格式错误！");

        //RuleFor(v => v.RoleIds)
        //     .MustAsync(BeRoleExistsAsync).WithMessage($"角色不存在！");

        //RuleFor(v => v.ParentId)
        //     .MustAsync(BeExistParentIdAsync).WithMessage($"上级不存在！");

        //RuleFor(v=>v.ParentId)
        //    .MustAsync(BeValidParentIdWithUserIdAsync).WithMessage($"上级不能是自己本身！");
    }

    /// <summary>
    /// 校验邮箱
    /// </summary>
    /// <param name="email">邮箱</param>
    /// <returns></returns>
    private bool BeValidEmail(string email)
    {
        if (email.IsNullOrWhiteSpace()) return true;

        return email.IsValidEmail();
    }

    /// <summary>
    /// 校验手机号码
    /// </summary>
    /// <param name="phoneNumber">手机号码</param>
    /// <returns>返回布尔值</returns>
    private bool BeValidPhoneNumber(string phoneNumber)
    {
        if (phoneNumber.IsNullOrWhiteSpace()) return true;

        return phoneNumber.IsValidPhoneNumber();
    }

    /// <summary>
    /// 检查角色是否存在
    /// </summary>
    /// <param name="roleIds"></param>
    /// <param name="cancellationToken"></param>
    /// <returns></returns>
    private async Task<bool> BeRoleExistsAsync(List<long>? roleIds, CancellationToken cancellationToken)
    {
        if (roleIds == null) return true;

        var existingRoles = await _context.Roles.Where(x => roleIds.Contains(x.Id)).ToListAsync();
        if (existingRoles == null || roleIds.Count != existingRoles.Count) return false;

        // 检查是否所有传入的角色ID都在数据库中存在且数量一致
        bool allIdsMatched = existingRoles.Select(r => r.Id).All(roleIds.Contains);

        return allIdsMatched;
    }

    /// <summary>
    /// 上级唯一标识是否存在
    /// </summary>
    /// <param name="parentId">上级唯一标识</param>
    /// <param name="cancellationToken">取消标记</param>
    /// <returns>返回布尔值</returns>
    private async Task<bool> BeExistParentIdAsync(long? parentId, CancellationToken cancellationToken)
    {
        if (parentId.HasValue) return await _context.Users.Where(x => x.Id == parentId).AnyAsync(cancellationToken);

        return true;
    }

    /// <summary>
    /// 校验用户唯一标识与上级唯一标识是否一至
    /// </summary>
    /// <param name="command">修改参数</param>
    /// <param name="parentId">上级唯一标识</param>
    /// <param name="cancellationToken">取消标记</param>
    /// <returns>返回布尔值</returns>
    private async Task<bool> BeValidParentIdWithUserIdAsync(UpdateUserCommand command, long? parentId, CancellationToken cancellationToken)
    {
        return await Task.Run(() => 
        {
            return command.UserId != parentId;
        });
    }
}